/**
 * 
 */
package org.swing.utility.jai.geometry;

import java.util.ArrayList;
import java.util.List;

/**
 * @author lqnhu
 *
 */
public class Circle {
	private Position center;
	private int radius;

	public Circle(Position p, int radius) {
		this.center = p;
		this.radius = radius;
	}

	public List<Position> getPoints() {
		List<Position> ret = new ArrayList<Position>();
		int d = 3 - (2 * radius);
		Position runner = new Position(0, radius);
		Position zero = new Position(0, 0);
		while (true) {
			if (Position.flatDistance(zero, runner) <= radius)
				addPoints(center, runner.x, runner.y, ret);
			if (d < 0)
				d = d + (4 * runner.x) + 6;
			else {
				d = d + 4 * (runner.x - runner.y) + 10;
				runner.y--;
			}
			runner.x++;
			if (runner.y == 0)
				break;
		}
		return ret;
	}

	private void addPoints(Position center, int x, int y,
			List<Position> collection) {
		collection.add(new Position(center.x + x, center.y + y));
		collection.add(new Position(center.x + x, center.y - y));
		collection.add(new Position(center.x - x, center.y + y));
		collection.add(new Position(center.x - x, center.y - y));
		collection.add(new Position(center.x + y, center.y + x));
		collection.add(new Position(center.x + y, center.y - x));
		collection.add(new Position(center.x - y, center.y + x));
		collection.add(new Position(center.x - y, center.y - x));
	}

}

class Position implements java.io.Serializable {
	public int x, y, z;

	public int x() {
		return x;
	}

	public int y() {
		return y;
	}

	public int z() {
		return z;
	}

	public Position(int px, int py) {
		x = px;
		y = py;
	}

	public Position(int px, int py, int pz) {
		this(px, py);
		z = pz;
	}

	public Position(Position p) {
		x = p.x;
		y = p.y;
		z = p.z;
	}

	public static Position add(Position a, Position b) {
		return new Position(a.x + b.x, a.y + b.y, a.z + b.z);
	}

	public static Position subs(Position a, Position b) {
		return new Position(a.x - b.x, a.y - b.y, a.z - b.z);
	}

	public static Position mul(Position a, int c) {
		return new Position(a.x * c, a.y * c, a.z * c);
	}

	public static Position mul(Position a, Position b) {
		return new Position(a.x * b.x, a.y * b.y, a.z * b.z);
	}

	public void mul(Position pos) {
		x *= pos.x;
		y *= pos.y;
		z *= pos.z;
	}

	public boolean equals(Object o) {
		if (o == null)
			return false;
		try {
			if (((Position) o).x == x && ((Position) o).y == y
					&& ((Position) o).z == z) {
				return true;
			}
		} catch (ClassCastException cce) {
			throw new RuntimeException("Error comparing points " + this + " "
					+ o, cce);
		}
		return false;
	}

	public int hashCode() {
		return toString().hashCode();
	}

	public String toString() {
		return "(" + x + "," + y + "," + z + ")";
	}

	public static int flatDistance(Position a, Position b) {
		return (int) Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2));
	}

	public static int flatDistance(int x1, int y1, int x2, int y2) {
		return (int) Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
	}

	public static int distance(Position a, Position b) {
		return (int) Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2));
	}

	/*
	 * public static int distance(Position a, Position b){ return (int)
	 * Math.s(Math.pow(a.x - b.x, 2) + Math.pow (a.y - b.y, 2)); }
	 */

	public void add(Position p) {
		x += p.x;
		y += p.y;
		z += p.z;

	}

}
